/*
 * descomentador.c
 *
 *  Created on: 02/09/2011
 *      Author: guido
 */

#include "descomentador.h"
#include <string.h>


void Descoment_init(Descomentador* d) {
	d->hayComentarioAbierto = 0;
	d->lineaSalida = d->lineaSalidaArray;
	d->lineaTemp = d->lineaTempArray;
	d->finDeLinea = 0;
}

/* Borra comentarios de la linea pasada por parametro.
 * Para hacerlo, primero las copia temporalmente en la estructura
 * del descomentador, y sobreescribe la salida en el parametro de
 * entrada. El dato finDeLinea avisa cuando termino de procesar
 * la entrada */
void Descoment_borrarComentarios(Descomentador* d, char* entrada) {
	Descoment_cargarLinea(d, entrada);
	while (!(d->finDeLinea)) {
		Descoment_cerrarComentario(d);
		Descoment_abrirDobleBarra(d);
		Descoment_abrirBarraAsterisco(d);
		if (!Descoment_quedanSimbolosDeComentario(d) && !(d->finDeLinea)) {
			d->finDeLinea = 1;
			strcat(d->lineaSalida,d->lineaTemp);
		}
	}
	strcpy(entrada,d->lineaSalida);
}

void Descoment_cargarLinea(Descomentador* d, char* entrada) {
	d->lineaSalida[0] = 0;
	strcpy(d->lineaTemp, entrada);
	d->finDeLinea = 0;
}

/* Si hay comentarios abierto, se ocupa de buscar hasta
 * encontrar un cierre de comentario. Si lo encuentra
 * cierra el comentario, si no lo encuentra borra toda la
 * linea */
void Descoment_cerrarComentario(Descomentador* d) {
	if (d->hayComentarioAbierto) {
		char* pos = strstr(d->lineaTemp, COMENTARIO_CERRADO);
		if (pos != NULL) {
			/*Encontro cierre de comentario, muevo el puntero para
			  para no copiar el token*/
			pos++;
			pos++;
			d->lineaTemp = pos;
			d->hayComentarioAbierto = 0;
		} else {
			/*Hay un comentario abierto, pero no se encontro
			  cierre en la linea actual; la linea se borra toda */
			d->lineaTemp[0] = FIN_DE_LINEA;
			d->lineaTemp[1] = 0;
			d->finDeLinea = 1;
		}
	}
}

/* Abre comentario de doble barra */
void Descoment_abrirDobleBarra(Descomentador* d) {
	char* posDobleBarra = strstr(d->lineaTemp, DOBLE_BARRA);
	if (posDobleBarra != NULL) {
		/*Se encontro doble barra, se copia todo hasta
		 * la doble barra, lo demas se desecha */
		posDobleBarra[0] = FIN_DE_LINEA;
		posDobleBarra[1] = 0;
		strcat(d->lineaSalida, d->lineaTemp);
		d->finDeLinea = 1;
	}
}

/* Abre comentario de barra asterisco */
void Descoment_abrirBarraAsterisco(Descomentador* d) {
	char* posBarraAsterisco = strstr(d->lineaTemp, COMENTARIO_ABIERTO);
	if (posBarraAsterisco != NULL) {
		/*Se encontro comentario abierto, se copia todo hasta
		 * el comentario, se mueve el puntero para no
		 * copiar el token */
		posBarraAsterisco[0] = 0;
		strcat(d->lineaSalida, d->lineaTemp);
		d->lineaTemp = posBarraAsterisco;
		d->lineaTemp++;
		d->lineaTemp++;
		d->hayComentarioAbierto = 1;
	}
}

/* Avisa si quedan comentarios sin procesar en la linea */
int Descoment_quedanSimbolosDeComentario(Descomentador* d) {
	int resultado = 1;
	if (!(d->hayComentarioAbierto) ) {
		if ( (strstr(d->lineaTemp,COMENTARIO_ABIERTO) == NULL)
				&& (strstr(d->lineaTemp,DOBLE_BARRA) == NULL) ) {
			resultado = 0;
		}
	}
	return resultado;
}
